<template>
    <div class="layer layer-text" :class="{ active: active }">
        <!-- 图片内容 -->
        <div class="layer-info">
            <figure>
                <i class="iconfont icon-tianjiawenzi-liebiaozuoduan"></i>
            </figure>
            <h2 v-text="layerText"></h2>
            <div class="handle" @click="setActive(layer)"></div>
            <div class="layer-info-button">
                <slot></slot>
            </div>
        </div>

        <!-- 图片因数 -->
        <div class="layer-factor">
            <label class="factor-text"><input type="text" v-model="layerText" ref="content"
                       @blur="textBlur()" /></label>

            <!-- 字体与颜色 -->
            <div class="factor-color">
                <div class="factor-color-family">
                    <span>Font</span>
                    <el-select v-model="layerFontFamily" placeholder="">
                        <el-option v-for="font in fontsJson" :key="font.name" :value="font.name">
                            <span v-text="font.name" :style="{ fontFamily: font.name }"></span>
                        </el-option>
                    </el-select>
                </div>

                <div class="factor-color-flex">
                    <UxColorPicker name="Color" v-model="fontColor" />

                    <UxColorPicker name="Outline" v-model="outlineColor">
                        <UxInputSlider name="Weight" v-model="outlineWeight" :step="0.001" :min="0" :max="1" />
                    </UxColorPicker>

                    <UxColorPicker name="Shadow" v-model="shadowColor">
                        <!-- <UxInputSlider name="Shadow blur" v-model="shadowBlur" :step="0.01" :min="0" :max="1" /> -->
                        <UxInputSlider name="Shadow distance" v-model="shadowDistance" :step="0.01" :min="0" :max="1" />
                        <UxInputSlider name="Shadow angle" v-model="shadowAngle" :step="1" :min="0" :max="360" />
                    </UxColorPicker>
                </div>
            </div>

            <!-- 位置大小 -->
            <div class="factor-input">
                <UxInputNumber name="Font size" unit="%" v-model="layerFontSize" :min="1" :max="1000" :step="0.1"
                               :precision="2" />
                <UxInputNumber name="Rotate" unit="deg" v-model="layerRotate" :step="1" :min="0" :max="360" />
                <UxInputNumber name="Right" unit="%" v-model="layerLeft" :precision="2" :step="0.1"
                               :min="layerRange.minX" :max="100" />
                <UxInputNumber name="Down" unit="%" v-model="layerTop" :precision="2" :step="0.1" :min="layerRange.minY"
                               :max="100" />
            </div>

            <!-- 滑块 -->
            <div class="factor-slider">
                <UxInputSlider name="Letter spacing" v-model="layerLetterSpacing" :max="1" :min="-0.25" :precision="2"
                               :step="0.1" />
                <!-- <UxInputSlider
                    name="Arc"
                    v-model="fontArc"
                    :max="360"
                    :min="0"
                    :step="1"
                /> -->
            </div>

            <!-- 对齐 -->
            <div class="factor-align">
                <button @click="setAlign('left')" title="Left align">
                    <svg-icon name="tooler-left" />
                </button>
                <button @click="setAlign('center')" title="Horizontal center align">
                    <svg-icon name="tooler-center" />
                </button>
                <button @click="setAlign('right')" title="right align">
                    <svg-icon name="tooler-right" />
                </button>
                <button @click="setAlign('top')" title="Top align">
                    <svg-icon name="tooler-top" />
                </button>
                <button @click="setAlign('middle')" title="Vertical center align">
                    <svg-icon name="tooler-middle" />
                </button>
                <button @click="setAlign('bottom')" title="Bottom align">
                    <svg-icon name="tooler-bottom" />
                </button>
            </div>

            <!-- 翻转 -->
            <div class="factor-flip">
                <button @click="setTypes('hor')" :class="{ active: layer.flipX }" title="Flip horizontal">
                    <svg-icon name="tooler-fliphor" />
                </button>
                <button @click="setTypes('ver')" :class="{ active: layer.flipY }" title="Flip vertical">
                    <svg-icon name="tooler-flipver" />
                </button>

                <button></button>
                <button></button>
                <button></button>

                <button @click="setTypes('reset')">
                    <svg-icon name="tooler-reset" />
                </button>
            </div>
        </div>
    </div>
</template>

<script>

import { mapGetters } from "vuex";
import DesignResource from "@/utils/DesignResource.js";
import DesignUtils from "@/utils/DesignUtils.js";
export default {
    props: {
        layer: {
            type: Object,
            required: true,
        },
        piece: {
            type: Object,
            required: true,
        },
    },
    data () {
        return {
            fontsJson: DesignResource.fontsJson,
            attribute: null,
        };
    },
    computed: {
        ...mapGetters('designer', {
            activeLayer: 'getActiveLayer',
        }),
        active () {
            return this.layer == this.activeLayer;
        },
        layerText: {
            get () {
                return this.layer.text;
            },
            set (value) {
                if (this.layer.text != value) {
                    const option = {
                        font_size: this.layer.font_size,
                        font_family: this.layer.font_family,
                        letter_spacing: this.layer.letter_spacing,
                        text: value,
                    }
                    this.$store.commit('designer/SET_LAYER_VALUE', { text: value });
                    this.resetTextSize(option);
                }
            }
        },
        layerFontSize: {
            get () {
                const piece = this.piece || {};
                const layer = this.layer;
                const w = piece.canvas_width || 1;
                const h = piece.canvas_height || 1;
                return 100 * layer.font_size / Math.min(w, h);
            },
            set (value) {

                const piece = this.piece || {};
                const layer = this.layer;
                const w = piece.canvas_width || 1;
                const h = piece.canvas_height || 1;

                const format = 0.01 * value * Math.min(w, h);

                if (this.layer.font_size != format) {
                    const option = {
                        font_size: format,
                        font_family: this.layer.font_family,
                        letter_spacing: this.layer.letter_spacing,
                        text: this.layer.text,
                    }

                    this.$store.commit('designer/SET_LAYER_VALUE', { font_size: format });
                    this.resetTextSize(option);
                }
            }
        },
        layerFontFamily: {
            get () {
                return this.layer.font_family;
            },
            set (value) {
                if (this.layer.text != value) {
                    const option = {
                        font_size: this.layer.font_size,
                        font_family: value,
                        letter_spacing: this.layer.letter_spacing,
                        text: this.layer.text,
                    }
                    this.$store.commit('designer/SET_LAYER_VALUE', { font_family: value });
                    DesignResource.loadFont(value).then(e => {
                        this.resetTextSize(option)
                    }).catch(error => {
                        this.resetTextSize(option)
                    })
                }
            }
        },
        layerLetterSpacing: {
            get () {
                return this.layer.letter_spacing;
            },
            set (value) {
                if (this.layer.text != value) {
                    const option = {
                        font_size: this.layer.font_size,
                        font_family: this.layer.font_family,
                        letter_spacing: value,
                        text: this.layer.text,
                    }
                    this.$store.commit('designer/SET_LAYER_VALUE', { letter_spacing: value });
                    this.resetTextSize(option);
                }
            }
        },

        fontColor: {
            get () { return this.layer.font_color; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { font_color: v }); }
        },
        outlineColor: {
            get () { return this.layer.outline_color; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { outline_color: v }); }
        },
        shadowColor: {
            get () { return this.layer.shadow_color; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { shadow_color: v }); }
        },
        fontArc: {
            get () { return this.layer.font_arc; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { font_arc: v }); }
        },
        outlineWeight: {
            get () { return this.layer.outline_weight; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { outline_weight: v }); }
        },
        shadowBlur: {
            get () { return this.layer.shadow_blur; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { shadow_blur: v }); }
        },
        shadowDistance: {
            get () { return this.layer.shadow_distance; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { shadow_distance: v }); }
        },
        shadowAngle: {
            get () { return this.layer.shadow_angle; },
            set (v) { this.$store.commit('designer/SET_LAYER_VALUE', { shadow_angle: v }); }
        },

        layerRotate: {
            get () {
                // return this.layer.rotate + this.piece.canvas_rotate;
                return this.layer.rotate;
            },
            set (value) {
                // const rotate = value - this.piece.canvas_rotate;
                const rotate = value;
                // const format = parseInt((180 + rotate) % 360 - 180) || 0;
                this.$store.commit('designer/SET_LAYER_VALUE', { rotate: rotate });
            }
        },

        layerRange () {
            const piece = this.piece || {};
            const layer = this.layer;
            const w = piece.canvas_width || 1;
            const h = piece.canvas_height || 1;

            return {
                minX: - 100 * layer.w / w,
                minY: - 100 * layer.h / h,
            }
        },

        layerLeft: {
            get () {
                const layer = this.layer;
                const piece = this.piece;

                const pieceSize = this.getPieceSize(piece);
                const layerSize = this.getLayerSize(piece, layer);

                // const θ = (360 + piece.canvas_rotate) * Math.PI / 180;
                const θ = (360) * Math.PI / 180;
                const xc = layer.x + 0.5 * layer.w - 0.5 * piece.canvas_width;
                const yc = layer.y + 0.5 * layer.h - 0.5 * piece.canvas_height;
                const x = xc * Math.cos(θ) - yc * Math.sin(θ);

                return 100 * (0.5 * pieceSize.width + x - 0.5 * layerSize.width) / pieceSize.width

            },
            set (value) {

                if (this.layerLeft != value) {

                    const left = value;
                    const top = this.layerTop;

                    const layer = this.layer;
                    const piece = this.piece;

                    const pieceSize = this.getPieceSize(piece);
                    const layerSize = this.getLayerSize(piece, layer);

                    // const θ = (360 - piece.canvas_rotate) * Math.PI / 180;
                    const θ = (360) * Math.PI / 180;

                    const xc = 0.01 * left * pieceSize.width + 0.5 * layerSize.width - 0.5 * pieceSize.width;
                    const yc = 0.01 * top * pieceSize.height + 0.5 * layerSize.height - 0.5 * pieceSize.height;

                    const x1 = xc * Math.cos(θ) - yc * Math.sin(θ);
                    const y1 = xc * Math.sin(θ) + yc * Math.cos(θ);

                    const change = {
                        x: x1 - 0.5 * layer.w + 0.5 * piece.canvas_width,
                        y: y1 - 0.5 * layer.h + 0.5 * piece.canvas_height,
                    }

                    this.$store.commit('designer/SET_LAYER_VALUE', change);
                }
            }
        },
        layerTop: {
            get () {

                const layer = this.layer;
                const piece = this.piece;

                const pieceSize = this.getPieceSize(piece);
                const layerSize = this.getLayerSize(piece, layer);

                // const θ = (360 + piece.canvas_rotate) * Math.PI / 180;
                const θ = (360) * Math.PI / 180;
                const xc = layer.x + 0.5 * layer.w - 0.5 * piece.canvas_width;
                const yc = layer.y + 0.5 * layer.h - 0.5 * piece.canvas_height;
                const y = xc * Math.sin(θ) + yc * Math.cos(θ);

                return 100 * (0.5 * pieceSize.height + y - 0.5 * layerSize.height) / pieceSize.height;

            },
            set (value) {

                if (this.layerTop != value) {

                    const left = this.layerLeft;
                    const top = value;

                    const layer = this.layer;
                    const piece = this.piece;

                    const pieceSize = this.getPieceSize(piece);
                    const layerSize = this.getLayerSize(piece, layer);

                    // const θ = (360 - piece.canvas_rotate) * Math.PI / 180;
                    const θ = (360) * Math.PI / 180;

                    const xc = 0.01 * left * pieceSize.width + 0.5 * layerSize.width - 0.5 * pieceSize.width;
                    const yc = 0.01 * top * pieceSize.height + 0.5 * layerSize.height - 0.5 * pieceSize.height;

                    const x1 = xc * Math.cos(θ) - yc * Math.sin(θ);
                    const y1 = xc * Math.sin(θ) + yc * Math.cos(θ);

                    const change = {
                        x: x1 - 0.5 * layer.w + 0.5 * piece.canvas_width,
                        y: y1 - 0.5 * layer.h + 0.5 * piece.canvas_height,
                    }

                    this.$store.commit('designer/SET_LAYER_VALUE', change);
                }
            }
        },

    },

    watch: {
        active (newval, oldval) {
            newval && this.setFocus();
        }
    },

    methods: {

        // 选中
        setActive (layer) {
            if (this.activeLayer == layer) {
                this.$store.commit("designer/SET_ACTIVE_LAYER", null);
            } else {
                this.$store.commit("designer/SET_ACTIVE_LAYER", layer);
            }
        },

        // 对齐方式
        setAlign (type) {

            const pieceSize = this.getPieceSize(this.piece);
            const layerSize = this.getLayerSize(this.piece, this.layer);

            if (type == 'left') {
                // 水平居左
                this.layerLeft = 0;
            } else if (type == 'center') {
                // 水平居中
                this.layerLeft = 50 * (pieceSize.width - layerSize.width) / pieceSize.width;
            } else if (type == 'right') {
                // 水平居右
                this.layerLeft = 100 * (pieceSize.width - layerSize.width) / pieceSize.width;
            } else if (type == 'top') {
                // 垂直居上
                this.layerTop = 0;
            } else if (type == 'middle') {
                // 垂直居中
                this.layerTop = 50 * (pieceSize.height - layerSize.height) / pieceSize.height;
            } else if (type == 'bottom') {
                // 垂直居下
                this.layerTop = 100 * (pieceSize.height - layerSize.height) / pieceSize.height;
            }
        },

        // 排版
        setTypes (type) {
            const layer = this.layer;
            const piece = this.piece;
            if (type == 'hor') {
                this.$store.commit('designer/SET_LAYER_VALUE', { flipX: !layer.flipX });
            } else if (type == 'ver') {
                this.$store.commit('designer/SET_LAYER_VALUE', { flipY: !layer.flipY });
            } else if (type == 'tiled') {
                // 平铺
            } else if (type == 'reset') {
                // 重置
                this.$emit('global:DESIGN_RESET_LAYER', { layer: layer, piece: piece });
            }
        },

        // 失去售点
        textBlur () {
            const text = (this.layer.text || '').trim();
            if (text) {
                // 有内容不管
            } else {
                this.$emit("global:DESIGN_REMOVE_LAYER", this.layer);
            }
        },

        // 修改font_size或text后调整宽度
        resetTextSize (option) {

            const style = {
                textAlign: 'center',
                fontFamily: option.font_family,
                fontSize: option.font_size,
                lineHeight: option.font_size,
                charSpacing: option.letter_spacing,
            }
            const size = DesignUtils.getTextSize(option.text, style);
            const change = {
                x: this.layer.x + (this.layer.w - size.width) / 2,
                y: this.layer.y + (this.layer.h - size.height) / 2,
                w: size.width,
                h: size.height,
            }

            this.$store.commit('designer/SET_LAYER_VALUE', change);

        },

        // 设计区大小
        getPieceSize (piece) {

            const x1 = -piece.canvas_width;
            const y1 = piece.canvas_height;
            const x2 = piece.canvas_width;
            const y2 = piece.canvas_height;
            // const θ = (360 - piece.canvas_rotate) * Math.PI / 180;
            const θ = (360) * Math.PI / 180;

            const w1 = Math.abs(x1 * Math.cos(θ) - y1 * Math.sin(θ));
            const w2 = Math.abs(x2 * Math.cos(θ) - y2 * Math.sin(θ));
            const h1 = Math.abs(x1 * Math.sin(θ) + y1 * Math.cos(θ));
            const h2 = Math.abs(x2 * Math.sin(θ) + y2 * Math.cos(θ));

            return {
                width: Math.max(w1, w2),
                height: Math.max(h1, h2),
            }
        },
        // 图层大小
        getLayerSize (piece, layer) {

            const x1 = -layer.w;
            const y1 = layer.h;
            const x2 = layer.w;
            const y2 = layer.h;
            // const θ = (360 - piece.canvas_rotate - layer.rotate) * Math.PI / 180;
            const θ = (360 - layer.rotate) * Math.PI / 180;

            const w1 = Math.abs(x1 * Math.cos(θ) - y1 * Math.sin(θ));
            const w2 = Math.abs(x2 * Math.cos(θ) - y2 * Math.sin(θ));
            const h1 = Math.abs(x1 * Math.sin(θ) + y1 * Math.cos(θ));
            const h2 = Math.abs(x2 * Math.sin(θ) + y2 * Math.cos(θ));

            return {
                width: Math.max(w1, w2),
                height: Math.max(h1, h2),
            }
        },

        setFocus () {
            this.active && this.$nextTick(e => {
                this.$refs.content && this.$refs.content.focus();
            });
        }
    },
    mounted () {
        this.setFocus();
    },

};
</script>

<style lang="scss" scoped>
.factor-input .input-number::v-deep {

    &:nth-child(2) input {
        padding-right: 48px;
    }

    // padding-right: 40px;
}
</style>
